package com.megvii.koala.guard;

import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;

/**
 * Created by linyue on 16/1/8.
 */
public class BoxUDPValidator extends BoxValidator
{
    private DatagramSocket socket;

    private Thread listenThread;

    private Thread sendThread;

    private Object listenLock = new Object();

    private boolean validating = false;

    private boolean listening = false;

    private int id;

    private String address;

    private void listen()
    {
        try
        {
            listenThread = new Thread()
            {
                public void run()
                {
                    byte[] buffer = new byte[128];
                    final DatagramPacket packet = new DatagramPacket(buffer, buffer.length);
                    try
                    {
                        socket = new DatagramSocket();
                        socket.setSoTimeout(6000);
                        synchronized (listenLock)
                        {
                            listening = true;
                            listenLock.notify();
                        }
                        socket.receive(packet);
                        socket.close();
                        validating = false;
                        postValidResult(id, true);
                    }
                    catch (Exception e)
                    {
                        e.printStackTrace();
                        validating = false;
                        if (listener != null)
                        {
                            listener.onValidateResult(id, false);
                        }
                    }
                }
            };
            listenThread.start();
        }
        catch (Exception e)
        {
            //TODO 以防开的线程过多，以后改成用线程池
            e.printStackTrace();
        }
    }

    private void send()
    {
        try
        {
            sendThread = new Thread()
            {
                public void run()
                {
                    synchronized (listenLock)
                    {
                        if (!listening)
                        {
                            try
                            {
                                listenLock.wait();
                            }
                            catch (InterruptedException e)
                            {
                                e.printStackTrace();
                                return;
                            }
                        }
                    }
                    try
                    {
                        InetAddress serverAddress = InetAddress.getByName(address);
                        byte[] data = "hello".getBytes();
                        DatagramPacket packet = new DatagramPacket(data, data.length, serverAddress,
                                54321);
                        socket.send(packet);
                    }
                    catch (IOException e)
                    {
                        e.printStackTrace();
                    }
                }
            };
            sendThread.start();
        }
        catch (Exception e)
        {
            //TODO 以防开的线程过多，以后改成用线程池
            e.printStackTrace();
        }
    }

    @Override
    synchronized public boolean validate(int id, String address)
    {
        if (validating)
        {
            return false;
        }
        validating = true;
        this.id = id;
        this.address = address;
        listening = false;
        listen();
        send();
        return true;
    }

    @Override
    synchronized public void release()
    {
        if (socket != null)
        {
            socket.close();
        }
        if (sendThread != null)
        {
            sendThread.interrupt();
        }
    }
}
